﻿using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;

namespace G.Service.BLL
{
    public interface IResult
    {
        string GetSerializaString();
    }

    [DataContract]
    public class Result : IResult
    {
        [DataMember]
        public bool IsOK { get; set; }
        [DataMember]
        public string Msg { get; set; }

        public string GetSerializaString()
        {

            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            using (JsonWriter jsonWriter = new JsonTextWriter(sw))
            {
                jsonWriter.Formatting = Formatting.Indented;
                Write(this, this.GetType(), jsonWriter);
            }
            return sb.ToString();
        }

        private void Write(object target, Type type, JsonWriter jsonWriter)
        {
            if (type.IsValueType || type == typeof(string))
            {
                jsonWriter.WriteValue(target);
            }
            else if (type.GetInterface("IEnumerable") != null)
            {
                IEnumerable ar = target as IEnumerable;
                jsonWriter.WriteStartArray();
                foreach (var item in ar)
                {
                    Write(item, item.GetType(), jsonWriter);
                }
                jsonWriter.WriteEndArray();
            }
            else
            {
                jsonWriter.WriteStartObject();
                IEnumerable<PropertyInfo> ps = target.GetType().GetProperties();
                if (target.GetType().IsSubclassOf(typeof(System.Data.Objects.DataClasses.EntityObject)))
                    ps = ps.Where(c => (c.Name != "EntityKey" && c.Name != "EntityState"));
                foreach (var p in ps)
                {
                    var att = Attribute.GetCustomAttribute(p, typeof(DataMemberAttribute));
                    if (att == null)
                        continue;
                    var value = p.GetValue(target, null);
                    if (value == null)
                        continue;
                    jsonWriter.WritePropertyName(p.Name);
                    Write(value, p.PropertyType, jsonWriter);
                }
                jsonWriter.WriteEndObject();
            }
        }
    }

    [DataContract]
    public class Result<T> : Result
    {
        [DataMember]
        public T ResponseData { get; set; }
    }
}
